package com.adingxiong.cft.controller;

import com.adingxiong.cft.config.ApplicationProperties;
import com.adingxiong.cft.errors.Assert;
import com.adingxiong.cft.result.Result;
import com.adingxiong.cft.result.RetCode;
import com.adingxiong.cft.util.FastDFSClient;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @ClassName UploadController
 * @Description TODO
 * @Author xiongchao
 * @Date 2020/9/8 13:44
 **/
@RestController
@RequestMapping("/file")
@Api(tags = "文件管理")
@Slf4j
public class UploadController {

    @Autowired
    private FastDFSClient fastDFSClient;

    @Autowired
    private ApplicationProperties applicationProperties;


    @ApiOperation(value = "文件上传")
    @RequestMapping(value = "/upload" ,method = RequestMethod.POST)
    public Result upload(
            @RequestParam("file") MultipartFile file
    ){

        if(file == null || file.isEmpty()){
            return Result.failed("param is empoty");
        }
        String path = fastDFSClient.upload(file);
        return Result.success(path);

    }

    @ApiOperation(value = "删除文件")
    @RequestMapping(value = "/del" ,method = RequestMethod.GET)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "文件全路径" ,name = "url" ,required = true,dataType = "String",paramType = "query")
    })
    public Result delFile(String url){
        if(url == null || url.equals("")){
            return Result.failed("param is empoty");
        }
        try {
            fastDFSClient.delFile(url);
            return Result.success(true,"删除成功");
        } catch (Exception e){
            return Result.failed("system error ,please try again later");
        }


    }

    @ApiOperation(value = "文件下载")
    @GetMapping("/downLoad")
    public ResponseEntity<byte []> downLoadFile(
            @ApiParam(value = "文件路径",required = true) @RequestParam(value = "url" ,required = true) String url
    ) {
        try {
            byte[] bytes = fastDFSClient.downloadFile(url);

            String fileName =url.substring(url.lastIndexOf("/" +1));
            fileName = new String(fileName.getBytes("utf-8"),"ISO_8859_1");

            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            httpHeaders.setContentDispositionFormData("attachment", fileName);

            return new ResponseEntity<byte[]>(bytes,httpHeaders,HttpStatus.OK);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    @ApiOperation(value = "批量下载文件")
    @GetMapping("/downloads")
    public ResponseEntity<byte []> mutilFileDownLoad(
            @ApiParam(value = "文件路径 ,使用逗号拼接，",required = true) @RequestParam(value = "urls") String urls,
            HttpServletResponse response
    ){
        List<String> list = Arrays.asList(urls.split(","));
        String rootPath = applicationProperties.getUploadPath();
        File file = new File(rootPath);
        if(!file.exists()){
            file.mkdirs();
        }
        List<String> fileList = new ArrayList<>();
        try {
            File f = null;
            FileOutputStream fos = null;
            ZipOutputStream zos = null ;
            for(String url : list){
                String fileName = url.substring(url.lastIndexOf("/")+1);
                byte[] bytes = fastDFSClient.downloadFile(url);
                fileList.add(rootPath + "//" + fileName);
                f = new File(rootPath + "//" + fileName);
                fos = new FileOutputStream(f);
                fos.write(bytes,0,bytes.length);
            }
            zipFile(fileList,response);
            fos.flush();
            fos.close();
            return ResponseEntity.ok(null);
        } catch (Exception e){
            Assert.fail("Batch download file failed");
            return null;
        }

    }

    /**
     *  下载文件到制定路径
     * @param fileList
     */
    public void zipFile(List<String> fileList){

        String zipName ="批量下载.zip";
        String zipPath = applicationProperties.getUploadPath() + "//" + zipName;

        BufferedInputStream bis =null;
        try {
            ZipOutputStream zipOutput = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipPath)));
            for(String str :  fileList) {
                File  file = new File(str);
                if(!file.exists()){
                    log.error("文件被删除");
                    continue;
                }
                ZipEntry zEntry = new ZipEntry(file.getName());
                zipOutput.putNextEntry(zEntry);
                bis = new BufferedInputStream(new FileInputStream(file));
                byte[] buffer = new byte[1024];
                int read = 0;
                while((read = bis.read(buffer)) != -1){
                    zipOutput.write(buffer, 0, read);
                }
            }
            zipOutput.finish();
            bis.close();
            zipOutput.close();

        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
    }

    public void zipFile(List<String> fileUlr, HttpServletResponse response){
        byte [] bytes = new byte[1024];

        String zipFileName= "图片压缩下载";
        BufferedOutputStream bos = null ;
        FileInputStream in = null;
        ZipOutputStream out = null;
        try {
            bos = new BufferedOutputStream(response.getOutputStream());

            response.reset();
            response.setContentType("application/x-msdownload");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename=" + zipFileName + ".zip");

            out = new ZipOutputStream(bos);
            for(String str :  fileUlr) {
                File  file = new File(str);
                if(!file.exists()){
                    log.error("文件被删除");
                    continue;
                }
                ZipEntry zEntry = new ZipEntry(file.getName());
                out.putNextEntry(zEntry);
                in = new FileInputStream(file);
                byte[] buffer = new byte[1024];
                int read = 0;
                while((read = in.read(buffer)) != -1){
                    out.write(buffer, 0, read);
                }
            }
            out.close();
            bos.close();
            log.info("========= 文件压缩成功 ============");
        } catch (Exception e){
            Assert.fail("request fail");
        }
    }


}
